classdef CImage< handle & matlab.mixin.Copyable
    properties(Constant)
        quality = 10;
        wsize = 800;
        fixlap = 150;
    end
    properties
        imageHeight;
        imageWidth;
        imagePath;
        img;

        tol = 50;
        boxes;
        overlaps;        

        columns = 0; %图片分割时按行优先进行分割
        nums = 0;%%分割图像个数
    end
    methods(Static = true)
        function ret = getString(kk, cols)
           row = floor((kk - 1) / cols) + 1;
           col = mod((kk-1), cols) + 1;
           
           ret = ['(', num2str(row), ',', num2str(col), ')'];
        end
    end
    methods
        function obj = CImage(fileName) %返回值必须是一个obj
            obj.img = imread(fileName);
            obj.imageHeight = size(obj.img, 1);
            obj.imageWidth = size(obj.img, 2);
            obj.imagePath = fileName;
        end
        
        function showGrids(obj)
            image(obj.img)
            axis equal
            
% % %             [boxes, overlap] = obj.getPatchGrid();
            [boxes, overlap] = obj.getPatchGridEx();
            
            for i = 1 : size(boxes, 1)
                box = boxes(i, :);
                box(3:4) = [obj.wsize-1, obj.wsize-1];
                box(1:2) = box(1:2) + 1;
                rectangle('Position', box, 'EdgeColor','b')
            end
            
            return;
        end
        %% 最早版本，重叠区域不固定
        function [boxes, overlap] = getPatchGrid(obj)
            %             wsize = obj.wsize;
            szImage = [obj.imageWidth; obj.imageHeight];
            nTimes = ceil(szImage/obj.wsize);
            nRes = nTimes * obj.wsize - szImage;
            
            overlap = floor(nRes ./ (nTimes -1));
            
            ins = overlap < obj.tol;
            nTimes = nTimes + ins;
            nRes = nTimes * obj.wsize - szImage;
            
            overlap = floor(nRes ./ (nTimes -1));
            
            cols = 0 : obj.wsize - overlap(1) : szImage(1) - obj.wsize;
            rows = 0 : obj.wsize - overlap(2) : szImage(2) - obj.wsize;
            
            if rows(end) ~= szImage(2) - obj.wsize
                rows(end+1) = szImage(2) - obj.wsize;
            end
            if cols(end) ~= szImage(1) - obj.wsize
                cols(end+1) = szImage(1) - obj.wsize;
            end
            
            boxes = zeros(nTimes(1) * nTimes(2), 4);
            i = 0;
            for rr = 1 : nTimes(2)
                for cc = 1 : nTimes(1)
                    
                    left = cols(cc);%%不是matlab绘图，不+1
                    top  = rows(rr);
                    
                    box = [left, top, ...
                        left + obj.wsize - 1, ...
                        top  + obj.wsize - 1];
                    
                    i = i + 1;
                    boxes(i, :) = box;
                end
            end
            obj.boxes = boxes;
            obj.overlaps = overlap;
        end
        
        %% 更新版本，重叠区域按照固定的尺寸
        function [boxes, overlap, columns] = getPatchGridEx(obj)
            %             wsize = obj.wsize;
            overlap = [obj.fixlap; obj.fixlap];%固定尺寸
            wwSize  = obj.wsize - overlap;
            szImage = [obj.imageWidth; obj.imageHeight];
            nTimes = ceil(szImage ./ wwSize);
            
            factSize = nTimes .* wwSize + overlap;            
            nRes = factSize - szImage;    
            
            cols = 0 : wwSize : szImage(1) - obj.fixlap;
            rows = 0 : wwSize : szImage(2) - obj.fixlap;
            
            nTimes(1) = length(cols);
            nTimes(2) = length(rows);
            boxes = zeros(nTimes(1) * nTimes(2), 4);
            i = 0;
            for rr = 1 : nTimes(2)
                for cc = 1 : nTimes(1)
                    
                    left = cols(cc);%%不是matlab绘图，不+1
                    top  = rows(rr);
                    
                    box = [left, top, ...
                        left + obj.wsize - 1, ...
                        top  + obj.wsize - 1];
                    
                    i = i + 1;
                    boxes(i, :) = box;
                end
            end
            obj.boxes = boxes;
            obj.overlaps = overlap;
            obj.columns = nTimes(1);
            obj.nums = nTimes(1) * nTimes(2);
            columns = nTimes(1);
        end
        %%把一张图片分割为若干小图片
        function segImagePieces(obj, json_src, json_temp, img, args)
            boxes = obj.boxes;
            ww = obj.wsize;
            overlap = obj.overlaps;
            columns = obj.columns;%%2022-09-08
            if columns == 0 
                disp('error in columns')
                return
            end
            
            json_temp.json_data.imageHeight = ww;
            json_temp.json_data.imageWidth  = ww;
            
            [~, pureName, ~] = fileparts(args.fileName);
            save_seg_json_dir = args.save_seg_json_dir;
            save_seg_img_dir  = args.save_seg_img_dir;
            
            
            for i = 1 : size(boxes, 1)
                json_obj = copy(json_temp);
                
                rect = boxes(i, :);%%左上角与右下角坐标
% %                 img_sub = imcrop(img, [rect(1)+1, rect(2)+1, ww-1, ww-1]);%%matlab坐标+1
                img_sub = Helper.CropImage(img, rect, ww);
                
%                 row = floor((i-1) / columns) + 1;
%                 col = mod(i-1, columns) + 1;%%2022-09-08
                
%                 fileNo = [pureName, '_', num2str(i, '%02d')];
                %%fileNo = [pureName, '_(', num2str(row), ',', num2str(col), ')'];%%增加行列坐标在文件名上
                fileNo = [pureName, '_', CImage.getString(i, columns)];%%增加行列坐标在文件名上
                JsonName = fullfile(save_seg_json_dir, [fileNo, '.json']);
                ImgName = fullfile(save_seg_img_dir, [fileNo, '.jpg']);
                
                shapes = json_src.getShapesInRect(rect, overlap);
                
                json_obj.json_data.shapes = shapes;
                json_obj.setAttachedData(rect, overlap);%%增加自定义数据
                
                json_obj.encodeImageData(img_sub, ImgName, true);
                json_obj.saveJsonFile(JsonName);
            end
        end
        
        
    end
end